{$MODE objfpc}

unit PythonMethodObject;
//
// methodobject.h
//

// Method object interface

{ This is about the type 'builtin_function_or_method',
   not Python methods in user-defined classes.  See classobject.h
   for the latter. }

interface
	uses PythonTypes;

// Flag passed to newmethodobject
const
	METH_OLDARGS  = $0000;
	METH_VARARGS  = $0001;
	METH_KEYWORDS = $0002;
	
	// METH_NOARGS and METH_O must not be combined with the flags above.
	METH_NOARGS   = $0004;
	METH_O        = $0008;
	
	// METH_CLASS and METH_STATIC are a little different; these control
   // the construction of methods for a class.  These cannot be used for
   // functions in modules.
	METH_CLASS    = $0010;
	METH_STATIC   = $0020;

 	// METH_COEXIST allows a method to be entered eventhough a slot has
   // already filled the entry.  When defined, the flag allows a separate
   // method, "__contains__" for example, to coexist with a defined 
   // slot like sq_contains.
	METH_COEXIST   = $0040;

var 
	PyCFunction_Type: PyTypeObject; cvar; external;

	//
	// Method Chain
	//
	function Py_FindMethodInChain(chain: PyMethodChainPtr; obj: PyObjectPtr; meth: PChar): PyObjectPtr; cdecl; external;
		{$EXTERNALSYM Py_FindMethodInChain}

	//
	// Functions
	//
	function PyCFunction_GetFunction(obj: PyObjectPtr): PyCFunction; cdecl; external;
	function PyCFunction_GetSelf(obj: PyObjectPtr): PyObjectPtr; cdecl; external;
	function PyCFunction_GetFlags(obj: PyObjectPtr): Integer; 	cdecl; external; 
	function PyCFunction_Call(obj, obj1, obj2: PyObjectPtr): PyObjectPtr; cdecl; external;

	function Py_FindMethod(arr: Array of PyMethodDef; obj: PyObjectPtr; meth: PChar): PyObjectPtr; cdecl; external;
		{$EXTERNALSYM Py_FindMethod}

	function PyCFunction_NewEx(meth: PyMethodDefPtr; obj, obj1: PyObjectPtr): PyObjectPtr; cdecl; external;
		{$EXTERNALSYM PyCFunction_NewEx}

	//
	// Methods implemented here... map to #define in the C code.
	//
	function PyCFunction_Check(op: PyObjectPtr): Boolean;

	// Macros for direct access to these values. Type checks are *not*
	//   done, so use with care.
	function PyCFunction_GET_FUNCTION(func: PyCFunctionObjectPTr): PyCFunction;
	function PyCFunction_GET_SELF(func: PyCFunctionObjectPtr): PyObjectPtr;
	function PyCFunction_GET_FLAGS(func: PyCFunctionObjectPtr): Integer;

	function PyCFunction_New(ML: PyMethodDefPtr; SELF: PyObjectPtr): PyObjectPtr;


implementation

function PyCFunction_Check(op: PyObjectPtr): Boolean;
begin
	result := (op^.ob_type = @PyCFunction_Type);
end;

function PyCFunction_GET_FUNCTION(func: PyCFunctionObjectPtr): PyCFunction;
begin
	result := func^.m_ml^.ml_meth;
end;

function PyCFunction_GET_SELF(func: PyCFunctionObjectPtr): PyObjectPtr;
begin
	result := func^.m_self;
end;
	
function PyCFunction_GET_FLAGS(func: PyCFunctionObjectPtr): Integer;
begin
	result := func^.m_ml^.ml_flags;
end;

function PyCFunction_New(ML: PyMethodDefPtr; SELF: PyObjectPtr): PyObjectPtr;
begin
	result := PyCFunction_NewEx(ML, SELF, nil);
end;

end.